﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace XTYAPI.PLC
{
    /// <summary>
    /// 构建复杂的逻辑 汇编计算
    /// </summary>
    public class BitRun
    {    
        /// <summary>
        /// 变量表
        /// </summary>
        public Dictionary<string,bool> ValuePairs { get;private set; }=new Dictionary<string, bool>();
        /// <summary>
        /// 逻辑表
        /// </summary>
        public List<BitValue> LstBitValues { get;private set; } = new List<BitValue>();
        /// <summary>
        /// 第一步添加相关变量名
        /// </summary>
        /// <param name="name"></param>
        public void AddName(string name)
        {
            if (!ValuePairs.ContainsKey(name))
            {
                ValuePairs.Add(name,false);
            }
        }
        /// <summary>
        /// 第二步添加相关逻辑
        /// </summary>
        /// <param name="bitValues"></param>
        public void AddMode(List<BitValue> bitValues)
        {
            if (bitValues!=null)
            {
                LstBitValues = bitValues;
            }
        }
        /// <summary>
        /// 数字信号
        /// </summary>
        public  class BitValue
        {
            /// <summary>
            /// 变量名
            /// </summary>
            public string Name { get; set; }
            /// <summary>
            /// 状态
            /// </summary>
            public  bool State { get; set; }
           
            /// <summary>
            /// 计算模式
            /// </summary>
            public BitMode BitMode { get; set; }
        }
        /// <summary>
        /// 开始运算，死循环扫描
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public bool Run()
        {
            if (LstBitValues == null)
            {
                throw new Exception("计算块对象不能为空null");
            }
            if (LstBitValues.Count == 0)
            {
                throw new Exception("计算块对象的数量不能为空");
            }
            if (LstBitValues[0].BitMode != BitMode.LD && LstBitValues[0].BitMode != BitMode.LDN)
            {
                throw new Exception("计算块的对象第一位必须是LD或者LDI");
            }
            int lastIndex = LstBitValues.Count - 1;
            if (LstBitValues[lastIndex].BitMode != BitMode.OUT)
            {
                throw new Exception("计算块的对象最后一位必须是OUT");
            }
            bool outResult = false;
            foreach (BitValue bitValue in LstBitValues)
            {
                if (bitValue.BitMode!=BitMode.OUT)
                {
                    bitValue.State = ValuePairs[bitValue.Name];
                }
                
                switch (bitValue.BitMode)
                {
                    case BitMode.LD:
                        outResult = bitValue.State;
                        Debug.WriteLine("LD"+"\t" +bitValue.Name);
                        break;
                    case BitMode.LDN:
                        outResult = !bitValue.State;
                        Debug.WriteLine("LDN" + "\t" + bitValue.Name);
                        break;
                    case BitMode.OUT:
                        bitValue.State = outResult;
                        ValuePairs[bitValue.Name] = outResult;
                        Debug.WriteLine("OUT" + "\t" + bitValue.Name);
                        break;
                    case BitMode.OR:
                        outResult |= bitValue.State;
                        Debug.WriteLine("OR" + "\t" + bitValue.Name);
                        break;
                    case BitMode.ORI:
                        outResult |= !bitValue.State;
                        Debug.WriteLine("ORI" + "\t" + bitValue.Name);
                        break;
                    case BitMode.AND:
                        outResult &= bitValue.State;
                        Debug.WriteLine("AND" + "\t" + bitValue.Name);
                        break;
                    case BitMode.ANI:
                        outResult &= !bitValue.State;
                        Debug.WriteLine("ANDI" + "\t" + bitValue.Name);
                        break;
                    default:
                        break;
                }
            }

            return true;
        }
        /// <summary>
        /// 计算模式枚举
        /// </summary>
        public enum BitMode
        {
            /// <summary>
            /// 逻辑开始常开触点
            /// </summary>
            LD,
            /// <summary>
            /// 逻辑开始常闭触点
            /// </summary>
            LDN,
            /// <summary>
            /// 输出
            /// </summary>
            OUT,
            /// <summary>
            /// 或 并联常开触点
            /// </summary>
            OR,
            /// <summary>
            /// 或非 并联常闭触点
            /// </summary>
            ORI,
            /// <summary>
            /// 与 串联常开触点
            /// </summary>
            AND,
            /// <summary>
            /// 与非 串联常闭触点
            /// </summary>
            ANI
        }
    }
}
